Skip to content

revise the schema default type not null - #3752

Merged
sijie merged 45 commits into
apache:masterfrom
congbobo184:schema_type_notnull
Mar 19, 2019
Merged

revise the schema default type not null#3752
sijie merged 45 commits into
apache:masterfrom
congbobo184:schema_type_notnull

Conversation

@congbobo184

@congbobo184 congbobo184 commented Mar 5, 2019

Copy link
Copy Markdown
Contributor

Motivation

Fix #3741

Modifications

Support define not not allow null field in schema

Verifying this change

Add not allow null field schema verify

Does this pull request potentially affect one of the following parts:
If yes was chosen, please highlight the changes

Dependencies (does it add or upgrade a dependency): (no)
The public API: (no)
The schema: (yes)
The default values of configurations: (no)
The wire protocol: (no)
The rest endpoints: (no)
The admin cli options: (no)
Anything that affects deployment: (no)

@jerrypeng

jerrypeng commented Mar 5, 2019

Copy link
Copy Markdown
Contributor

@congbobo184 while I am ok if we decide to remove allow null from set by default, my only concern is this ix NOT a backwards compatible change.

@merlimat merlimat left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is breaking backward compatibility.

There needs to be a migration plan that allows us to identify that a schema was created with an earlier version of the client library and thus will let through a one-time no-check migration to the new default.

@merlimat

merlimat commented Mar 5, 2019

Copy link
Copy Markdown
Contributor

Since the Python schema generation is following the current behavior of the Java client. We also need to change the defaults there. Again, with migration path in mind.

@sijie

sijie commented Mar 5, 2019

Copy link
Copy Markdown
Member

@congbobo184 @jerrypeng @merlimat :

I don't think we should attempt to involve any data migration between schemas, that will be a nightmare.

what I would suggest here:

  1. adding a flag allowNull (by default to be true for backward compatibility). users have ability to disable allowNull.
  2. if user disabled allowNull, the AvroSchema will add a property entry avro.allowNull = false to the properties map of schema info. This property will be used for telling how the avro schema is generated. avro.allowNull doesn't exist or exists as true means the schema is generated using AllowNull; avro.allowNull == false means the schema is generated NOT using AllowNull.

so there are nothing else to be changed. but the documentation should be updated to highlight allowNull will introduce incompatibilities when same POJO classes used in other AVRO system.

@merlimat

merlimat commented Mar 5, 2019

Copy link
Copy Markdown
Contributor

Adding the flag and leave allowNull=true by default is good and easy.

I think though that using allowNull=false would be a better default option, but it doesn't have to be done right now in this PR.

Regarding the migration path, I'm not referring to migrate the schema definition, but rather to allow a one-time "incompatible" schema evolution marked with a version in pulsar schema registry.

@sijie

sijie commented Mar 5, 2019

Copy link
Copy Markdown
Member

Regarding the migration path, I'm not referring to migrate the schema definition, but rather to allow a one-time "incompatible" schema evolution marked with a version in pulsar schema registry.

supporting "incompatible" schema can't really be done using POJO schemas. we can support that using the generic schema stuffs that I recently work on. but there are still a lot of work to complete in that piece before we can claim we are ready to take such "incompatible" migration.

@merlimat

merlimat commented Mar 5, 2019

Copy link
Copy Markdown
Contributor

In this case the problem is that, if we change the default setting, the schema extracted from a given POJO will change. The user defined will still be the same though, as the data serialized by it.

@sijie

sijie commented Mar 5, 2019

Copy link
Copy Markdown
Member

@merlimat

The user defined will still be the same though, as the data serialized by it.

the user defined will be still the same. that's fine.
but in a AllowNull schema, a record can be omitting fields; but in a NOT AllowNull schema, all fields have constraints. so if a record is serialized with AllowNull schema is not SAFE to be deserialized by a NOT AllowNull schema even the user defined POJO are same.

The other way around is working - you are okay to use a AllowNull schema to deserialize the data serialized by a NOT AllowNull schema.

With that being explained, if we are using POJO schema, we can't really just "migrate" the schema in schema registry (or it is very very tricky to do so). We can do it by using MultiVersionedGenericSchema which I introduced a few days ago. For each message, it will be using the right schema to deserialize the record into a GenericRecord. But that's probably not useful for applications are using POJO schemas.

@jerrypeng

Copy link
Copy Markdown
Contributor

@sijie @congbobo184 @merlimat if we are removing AllowNull or allowing the flag to be configurable, should we also do it for JSONSchema:

https://github.com/apache/pulsar/blob/master/pulsar-client/src/main/java/org/apache/pulsar/client/impl/schema/JSONSchema.java#L63

@sijie

sijie commented Mar 5, 2019

Copy link
Copy Markdown
Member

@jerrypeng I am not sure we need to do it for JSON. because there is no real schema in JSON data. every field in a json struct is optional, no?

@merlimat

merlimat commented Mar 5, 2019

Copy link
Copy Markdown
Contributor

Thinking on this a bit more, I believe a better approach is to let the user specify the Avro schema definition directly, either in form of schema object or in json string.

That is because:

  • The schema definition is already the source of truth
  • I think that will be less confusing to people instead of thinking about whether to set allowNull=true/false and the implications of that.

The recommendation in the docs would be to pass the schema if you already have one.

@sijie

sijie commented Mar 6, 2019

Copy link
Copy Markdown
Member

@merlimat

let the user specify the Avro schema definition directly, either in form of schema object or in json string.

+1 on supporting specifying avro schema (via schema object or json). that's one of the schema tasks in my TODO list related schema builder.

Although I think it should be done in a separate PR.

* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

format license header

*/
static <K, V> Schema<KeyValue<K, V>> KeyValue(Class<K> key, Class<V> value, SchemaType type) {
return DefaultImplementation.newKeyValueSchema(key, value, type);
return DefaultImplementation.newKeyValueSchema(key, value, type,true);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add blank space

*/
static <K, V> Schema<KeyValue<K, V>> KeyValue(Class<K> key, Class<V> value) {
return DefaultImplementation.newKeyValueSchema(key, value, SchemaType.JSON);
return DefaultImplementation.newKeyValueSchema(key, value, SchemaType.JSON,true);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add blank space

}

public static <T> Schema<T> newAvroSchema(Class<T> clazz) {
public static <T> Schema<T> newAvroSchema(Class<T> clazz,Boolean allowNull) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add blank space

() -> (Schema<T>) getStaticMethod("org.apache.pulsar.client.impl.schema.AvroSchema", "of", Class.class)
.invoke(null, clazz));
() -> (Schema<T>) getStaticMethod("org.apache.pulsar.client.impl.schema.AvroSchema", "of", Class.class,Boolean.class)
.invoke(null, clazz,allowNull));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add blank space

@congbobo184

Copy link
Copy Markdown
Contributor Author

run Integration Tests

2 similar comments
@congbobo184

Copy link
Copy Markdown
Contributor Author

run Integration Tests

@congbobo184

Copy link
Copy Markdown
Contributor Author

run Integration Tests

@congbobo184

Copy link
Copy Markdown
Contributor Author

run java8 tests

@congbobo184

Copy link
Copy Markdown
Contributor Author

run Integration Tests

@congbobo184

Copy link
Copy Markdown
Contributor Author

run java8 tests

@congbobo184

Copy link
Copy Markdown
Contributor Author

run Integration Tests

1 similar comment
@congbobo184

Copy link
Copy Markdown
Contributor Author

run Integration Tests

@congbobo184

Copy link
Copy Markdown
Contributor Author

run Integration Tests

4 similar comments
@congbobo184

Copy link
Copy Markdown
Contributor Author

run Integration Tests

@congbobo184

Copy link
Copy Markdown
Contributor Author

run Integration Tests

@congbobo184

Copy link
Copy Markdown
Contributor Author

run Integration Tests

@congbobo184

Copy link
Copy Markdown
Contributor Author

run Integration Tests

@congbobo184

Copy link
Copy Markdown
Contributor Author

run Integration Tests

@sijie sijie modified the milestones: 2.4.0, 2.3.1 Mar 19, 2019
@sijie
sijie merged commit 1a1c557 into apache:master Mar 19, 2019
merlimat pushed a commit that referenced this pull request Mar 29, 2019
Fix #3741

Support define not not allow null field in schema

Add not allow null field schema verify

Does this pull request potentially affect one of the following parts:
If yes was chosen, please highlight the changes

Dependencies (does it add or upgrade a dependency): (no)
The public API: (no)
The schema: (yes)
The default values of configurations: (no)
The wire protocol: (no)
The rest endpoints: (no)
The admin cli options: (no)
Anything that affects deployment: (no)
@merlimat

merlimat commented Apr 1, 2019

Copy link
Copy Markdown
Contributor

Merged in 2.3.1 at
6e76af2

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/client type/enhancement The enhancements for the existing features or docs. e.g. reduce memory usage of the delayed messages

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants